import {
  AND_UPPER,
  ARGUMENT_DEFINITION_UPPER,
  BOOLEAN_SCALAR,
  CONNECT_FIELD_RESOLVER,
  CONSUMER_INACTIVE_THRESHOLD,
  CONSUMER_NAME,
  DEPRECATED,
  EDFS_KAFKA_PUBLISH,
  EDFS_KAFKA_SUBSCRIBE,
  EDFS_NATS_PUBLISH,
  EDFS_NATS_REQUEST,
  EDFS_NATS_STREAM_CONFIGURATION,
  EDFS_NATS_SUBSCRIBE,
  EDFS_REDIS_PUBLISH,
  EDFS_REDIS_SUBSCRIBE,
  ENUM_UPPER,
  ENUM_VALUE_UPPER,
  FIELD_DEFINITION_UPPER,
  FIELD_SET_SCALAR,
  FLOAT_SCALAR,
  ID_SCALAR,
  IN_UPPER,
  INPUT_FIELD_DEFINITION_UPPER,
  INPUT_OBJECT_UPPER,
  INT_SCALAR,
  INTERFACE_UPPER,
  KEY,
  LINK,
  LINK_IMPORT,
  LINK_PURPOSE,
  NOT_UPPER,
  OBJECT_UPPER,
  ONE_OF,
  OR_UPPER,
  PROVIDES,
  REQUIRES,
  REQUIRES_SCOPES,
  SCALAR_UPPER,
  SCHEMA_UPPER,
  SEMANTIC_NON_NULL,
  STREAM_NAME,
  STRING_SCALAR,
  SUBSCRIPTION_FIELD_CONDITION,
  SUBSCRIPTION_FILTER,
  SUBSCRIPTION_FILTER_CONDITION,
  SUBSCRIPTION_FILTER_VALUE,
  UNION_UPPER,
} from '../../utils/string-constants';
import { DefinitionNode, Kind } from 'graphql';
import { DirectiveName, FieldName, TypeName } from '../../types/types';
import {
  EDFS_NATS_STREAM_CONFIGURATION_DEFINITION,
  FIELD_SET_SCALAR_DEFINITION,
  LINK_IMPORT_DEFINITION,
  LINK_PURPOSE_DEFINITION,
  SCOPE_SCALAR_DEFINITION,
  SUBSCRIPTION_FIELD_CONDITION_DEFINITION,
  SUBSCRIPTION_FILTER_CONDITION_DEFINITION,
  SUBSCRIPTION_FILTER_VALUE_DEFINITION,
} from './non-directive-definitions';

export const TYPE_SYSTEM_DIRECTIVE_LOCATIONS: ReadonlySet<string> = new Set<string>([
  ARGUMENT_DEFINITION_UPPER,
  ENUM_UPPER,
  ENUM_VALUE_UPPER,
  FIELD_DEFINITION_UPPER,
  INPUT_FIELD_DEFINITION_UPPER,
  INPUT_OBJECT_UPPER,
  INTERFACE_UPPER,
  OBJECT_UPPER,
  SCALAR_UPPER,
  SCHEMA_UPPER,
  UNION_UPPER,
]);

export const EVENT_DIRECTIVE_NAMES: ReadonlySet<DirectiveName> = new Set<DirectiveName>([
  EDFS_KAFKA_PUBLISH,
  EDFS_KAFKA_SUBSCRIBE,
  EDFS_NATS_PUBLISH,
  EDFS_NATS_REQUEST,
  EDFS_NATS_SUBSCRIBE,
  EDFS_REDIS_PUBLISH,
  EDFS_REDIS_SUBSCRIBE,
]);

export const STREAM_CONFIGURATION_FIELD_NAMES: ReadonlySet<FieldName> = new Set<FieldName>([
  CONSUMER_INACTIVE_THRESHOLD,
  CONSUMER_NAME,
  STREAM_NAME,
]);

export const SUBSCRIPTION_FILTER_INPUT_NAMES: ReadonlySet<string> = new Set<string>([
  AND_UPPER,
  IN_UPPER,
  NOT_UPPER,
  OR_UPPER,
]);
export const SUBSCRIPTION_FILTER_LIST_INPUT_NAMES: ReadonlySet<string> = new Set<string>([AND_UPPER, OR_UPPER]);

export const COMPOSITE_OUTPUT_NODE_KINDS: ReadonlySet<Kind> = new Set<Kind>([
  Kind.INTERFACE_TYPE_DEFINITION,
  Kind.INTERFACE_TYPE_EXTENSION,
  Kind.OBJECT_TYPE_DEFINITION,
  Kind.OBJECT_TYPE_EXTENSION,
]);

export const DEPENDENCIES_BY_DIRECTIVE_NAME: ReadonlyMap<DirectiveName, Array<DefinitionNode>> = new Map<
  DirectiveName,
  Array<DefinitionNode>
>([
  [CONNECT_FIELD_RESOLVER, [FIELD_SET_SCALAR_DEFINITION]],
  [EDFS_NATS_SUBSCRIBE, [EDFS_NATS_STREAM_CONFIGURATION_DEFINITION]],
  [KEY, [FIELD_SET_SCALAR_DEFINITION]],
  [LINK, [LINK_IMPORT_DEFINITION, LINK_PURPOSE_DEFINITION]],
  [PROVIDES, [FIELD_SET_SCALAR_DEFINITION]],
  [REQUIRES, [FIELD_SET_SCALAR_DEFINITION]],
  [REQUIRES_SCOPES, [SCOPE_SCALAR_DEFINITION]],
  [
    SUBSCRIPTION_FILTER,
    [
      SUBSCRIPTION_FIELD_CONDITION_DEFINITION,
      SUBSCRIPTION_FILTER_CONDITION_DEFINITION,
      SUBSCRIPTION_FILTER_VALUE_DEFINITION,
    ],
  ],
]);

export const IGNORED_FEDERATED_TYPE_NAMES: ReadonlySet<TypeName> = new Set<TypeName>([
  BOOLEAN_SCALAR,
  EDFS_NATS_STREAM_CONFIGURATION,
  FIELD_SET_SCALAR,
  ID_SCALAR,
  INT_SCALAR,
  FLOAT_SCALAR,
  LINK_IMPORT,
  LINK_PURPOSE,
  STRING_SCALAR,
  SUBSCRIPTION_FIELD_CONDITION,
  SUBSCRIPTION_FILTER_CONDITION,
  SUBSCRIPTION_FILTER_VALUE,
]);

export const CLIENT_PERSISTED_DIRECTIVE_NAMES: ReadonlySet<DirectiveName> = new Set<DirectiveName>([
  DEPRECATED,
  ONE_OF,
  SEMANTIC_NON_NULL,
]);
